import logging


def get_value(dat: dict, *keys):
    """
    从字典对象中获取多层值，且不会抛出异常
    :param dat:
    :param keys:
    :return:
    """
    if dat is None:
        return None

    if not keys:
        return dat

    node = dat
    for key in keys:
        try:
            if isinstance(node, list):
                if isinstance(key, int):
                    node = node[key]

                elif isinstance(key, tuple):
                    node = find_in_list(node, key[0], key[1])

            elif isinstance(node, dict):
                node = node.get(key)

            else:
                node = None

            if node is None:
                return None

        except BaseException as ex:
            logging.exception(str(ex))

    return node


def find_in_list(dat: list, key: str, value):
    """
    在list<dict>中查找键值
    :param dat:
    :param key:
    :param value:
    :return:
    """
    if not isinstance(dat, list):
        return None

    try:
        for node in dat:
            if value == node.get(key):
                return node
    except BaseException:
        pass

    return None


if __name__ == '__main__':
    dat = {1: 999, 'v1': 1, 'v2': {25: 25, 'v21': 21, 'v22': 22, 23: {'v231': 231, 'v232': 232}}, 'v3': [{'v31': 31, 'key': 31}, {'v32': 32, 'key': 32}]}

    print(get_value(dat, None, 'v23'))
    print(get_value(dat, 'v1'))
    print(get_value(dat, 'v1', None))
    print(get_value(dat, 'v1', 'v23'))
    print(get_value(dat, 'v2', 23, 'v232'))

    print(get_value(dat, 'v3', ('v32', 32), 'v32'))
